package transfer

import (
	"../../common/socket"
	"../../common/utils"
	"encoding/json"
	"fmt"
	"net"
	"sync"
	"time"
)

var wr_lock sync.RWMutex
//在线的用户
var Users =make(map[string]net.Conn)
//下线的用户
var OfflineUserChannel=make(chan map[string]net.Conn,1024)

//调度
type Transfer struct {

}
//添加用户进入在线列表
func (this *Transfer) AddUser(id string,user net.Conn){
	Users[id]=user
	fmt.Println(id,"已上线")
}

//该用户由于网络的原因,发送失败,扔进下线队列,然后删除该用户
func (this *Transfer) DelUser(id string,conn net.Conn){

	offlineUser:=make(map[string]net.Conn)
	offlineUser[id]=conn
	OfflineUserChannel<-offlineUser
	wr_lock.Lock()
	delete(Users,id)
	fmt.Println(id,"已下线")
	wr_lock.Unlock()
}

//获取当前用户在线列表
func (this *Transfer) GetOnlineUser() []string{
	var arr  []string
	for k,_:=range Users {
		arr=append(arr,k)
	}
	return  arr
}


/**
	上线通知其他用户
 */

type Notify struct {

}

//心跳包
func (this *Notify) HeartBeat(){
	go func() {
		data:=new(socket.Data)
		data.DataType=socket.HeartBeat
		data.Message=""
		byte,err:=json.Marshal(data)
		transfer:=new(Transfer)
		for  {
			for uid,conn:=range Users{
				_,err=conn.Write(byte)
				if err!=nil {
					//由于网络原因,删除该用户
					transfer.DelUser(uid,conn)
				}
			}
			//每一秒发送一次心跳包
			time.Sleep(time.Second*3)
		}
	}()
}


//通知其他用户有人上限
func (this *Notify) NotifyOtherUserOnline(id string){
	data:=new(socket.Data)
	data.DataType=socket.FriendStatus
	data.Message="用户:"+id+"上线了"
	byte,err:=json.Marshal(data)
	utils.HanddleError(err,"通知其他用户好友上线失败")
	wr_lock.RLock()
	for uid,conn:=range Users{
		if id==uid {
			continue
		}
		_,err=conn.Write(byte)
		if err!=nil {
			fmt.Println(err)
		}
	}
	wr_lock.RUnlock()

}


//通知其他用户有人下线
func (this *Notify) NotifyOtherUserOffline(){
	go func() {
		data:=new(socket.Data)
		data.DataType=socket.FriendStatus
		var message string
		for value:=range OfflineUserChannel{
			for id,_:=range value {
				message="用户:"+id+"下线了\n"
			}
			data.Message=message
			byte,err:=json.Marshal(data)
			utils.HanddleError(err,"通知其他用户好友下线失败")
			for _,conn:=range Users{
				_,err=conn.Write(byte)
				if err!=nil {
					fmt.Println(err)
				}
			}
		}
	}()
}


func (this *Notify) ReceiveUserMenu(){

}







func init(){

}